﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Collections;

namespace FACUI.frmDialog
{
    public class GetSource
    {
        private UdpClient _udp = null;
        private IPEndPoint _ipe = null;
        private FileStream _fs = null;
        private string curFileName = string.Empty;
        private DateTime _startTime = DateTime.Now;
        private long lCount = 0;

        public GetSource(int iRecPort)
        {
            try
            {
                _udp = new UdpClient(iRecPort);
                _ipe = new IPEndPoint(IPAddress.Any, iRecPort);
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
        }

        public void ReceiveData()
        {
            Queue<byte[]> CurSecSorce = new Queue<byte[]>(2*1024*1024);
            DateTime dt = DateTime.Now.AddMilliseconds(50);
            DateTime dlog = DateTime.Now.AddSeconds(1);
            while (true)
            {                
                try
                {
                    byte[] bytes = _udp.Receive(ref _ipe);
                    if (bytes.Length % 512 != 0) continue;
                    //计算显示波长信息
                    ThreadPool.QueueUserWorkItem(new WaitCallback(DrawWavLen),bytes.Clone());

                    //不再保存信息

                    //byte[] bytes = _udp.Receive(ref _ipe);
                    //if (bytes.Length % 512 != 0) continue;
                    ////保存原始数据
                    ////ThreadPool.QueueUserWorkItem(new WaitCallback(SaveBuffer), _bb);
                    //SaveBuffer(bytes);
                    //FACUI.BasicClass.CGlobal.lDataCount += bytes.Length;
                    //CurSecSorce.Enqueue(bytes);
                    //lCount += 512;
                    //if (dt <= DateTime.Now)
                    //{
                    //    dt = DateTime.Now.AddMilliseconds(50);
                    //    lCount = 0;
                    //    byte[][] _bb = CurSecSorce.ToArray();
                    //    CurSecSorce.Clear();
                    //    //计算显示波长信息
                    //    ThreadPool.QueueUserWorkItem(new WaitCallback(DrawWavLen), _bb);
                    //    //显示光谱信息
                    //    //ThreadPool.QueueUserWorkItem(new WaitCallback(WriteBytesToDouble), bytes);
                        
                    //    CurSecSorce.Clear();
                    //}
                    //if (dlog <= DateTime.Now)
                    //{
                    //    dlog = DateTime.Now.AddSeconds(1);
                    //    CSource.mutqlong.WaitOne();
                    //    CSource._Quelong.Enqueue(lCount);
                    //    CSource.mutqlong.ReleaseMutex();
                    //}
                }
                catch (Exception ex){ System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
            }
        }
        /// <summary>
        /// 写原始光谱到缓冲区
        /// </summary>
        /// <param name="o"></param>
        private void WriteBytesToDouble(object o)
        {
            try
            {
                byte[] bytes = o as byte[];
                byte[] _tmp = (byte[])bytes.Clone();
                if (_tmp.Length % 512 != 0) return;
                double[] _tmpData = new double[256];
                for (int n = 0; n < 256; n++)
                {
                    _tmpData[n] = double.Parse(BitConverter.ToUInt16(_tmp, 2 * n).ToString());
                }
                CSource.dSpectrum = _tmpData;
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
        }
        /// <summary>
        /// 保存原始光谱到文件
        /// </summary>
        /// <param name="o"></param>
        private void SaveBuffer(object o)
        {
            try
            {
                byte[][] _bb = o as byte[][];
                byte[][] _Atmp = (byte[][])_bb.Clone(); 
                if (curFileName == string.Empty)
                {
                    _startTime = DateTime.Now;
                    curFileName = string.Format("{0}.dat", _startTime.ToString("yyyyMMddHHmmss"));
                }
                if (_startTime.AddMinutes(30) <= DateTime.Now)
                {
                    _startTime = DateTime.Now;
                    curFileName = string.Format("{0}.dat", _startTime.ToString("yyyyMMddHHmmss"));
                }
                CSource.mutsavesource.WaitOne();
                if (!File.Exists(CSource.strDirPath + "\\" + curFileName))
                {
                    if (_fs != null)
                    {
                        string strInx = _fs.Name;
                        _fs.Close();
                        _fs.Dispose();
                        _fs = null;
                        CSource.mutqlong.WaitOne();
                        int len = CSource._Quelong.Count;
                        if (len > 0)
                        {
                            long[] lArray = CSource._Quelong.ToArray();
                            CSource._Quelong.Clear();
                            lCount = 0;
                            CSource.mutqlong.ReleaseMutex();
                            FileStream _ffss = File.OpenWrite(strInx.Replace(".dat", ".inx"));
                            foreach (long l in lArray)
                            {
                                _ffss.Write(BitConverter.GetBytes(l),0,8);
                            }
                            _ffss.Close();
                        }
                        else
                        {
                            CSource.mutqlong.ReleaseMutex();
                        }
                    }
                    _fs = File.OpenWrite(CSource.strDirPath + "\\" + curFileName);
                }
                if (_fs == null)
                {
                    _fs = File.OpenWrite(CSource.strDirPath + "\\" + curFileName);
                    CSource.strCurPath = _fs.Name;
                }
                foreach (byte[] b in _Atmp)
                {
                    _fs.Write(b, 0, b.Length);
                }
                CSource.mutsavesource.ReleaseMutex();
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
        }
        /// <summary>
        /// 保存原始光谱到文件
        /// </summary>
        /// <param name="bytes"></param>
        private void SaveBuffer(byte[] bytes)
        {
            try
            {
                if (curFileName == string.Empty)
                {
                    _startTime = DateTime.Now;
                    curFileName = string.Format("{0}.dat", _startTime.ToString("yyyyMMddHHmmss"));
                }
                if (_startTime.AddMinutes(30) <= DateTime.Now)
                {
                    _startTime = DateTime.Now;
                    curFileName = string.Format("{0}.dat", _startTime.ToString("yyyyMMddHHmmss"));
                }
                if (!File.Exists(CSource.strDirPath + "\\" + curFileName))
                {
                    if (_fs != null)
                    {
                        string strInx = _fs.Name;
                        _fs.Close();
                        _fs.Dispose();
                        _fs = null;
                    }
                    _fs = File.OpenWrite(CSource.strDirPath + "\\" + curFileName);
                }
                if (_fs == null)
                {
                    _fs = File.OpenWrite(CSource.strDirPath + "\\" + curFileName);
                    CSource.strCurPath = _fs.Name;
                }
                _fs.Write(bytes, 0, bytes.Length);
                _fs.Flush();
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
        }

        /// <summary>
        /// 写时时波长到缓冲区
        /// </summary>
        /// <param name="o"></param>
        private void DrawWavLen(object o)
        {
            try
            {
                byte[] _bb = o as byte[];
                byte[] _Atmp = (byte[])_bb.Clone(); 
                Queue<double[]> _wav = new Queue<double[]>(10*8*1024);

                double[] _tmpData = new double[256];
                for (int n = 0; n < 256; n++)
                {
                    _tmpData[n] = double.Parse(BitConverter.ToUInt16(_Atmp, 2 * n).ToString());
                }
                double dAvrg = _tmpData.Average() + CSource.dAvgLevel;
                //double dAvrg = _tmpData.Average();
                for (int i = 0; i < _tmpData.Length; i++)
                {
                    if (_tmpData[i] <= dAvrg)
                    {
                        _tmpData[i] = 0;
                    }
                }
                double[] _wavlen = new double[30];
                CSource.GetWavesLength(_tmpData, ref _wavlen);
                _wav.Enqueue(_wavlen);
                CSource.mutqwavsrc.WaitOne();
                if (CSource._queWavSource.Count > 15)
                {
                    CSource._queWavSource.Dequeue();
                }
                CSource._queWavSource.Enqueue(_wav);
                CSource.mutqwavsrc.ReleaseMutex();
            }
            catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.StackTrace + ":" + ex.Message); }
        }
    }
}
